package com.kll.carolinehmibiz.presenter

import android.content.Context
import android.os.Handler
import android.os.Message
import com.google.gson.Gson
import com.kll.carolinehmibiz.base.net.NetCode
import com.kll.carolinehmibiz.base.net.bean.BaseHttpResult
import com.kll.carolinehmibiz.base.net.rx.NetObserver
import com.kll.carolinehmibiz.base.utils.L
import com.kll.carolinehmibiz.base.utils.SpUtils
import com.kll.carolinehmibiz.model.OperateListener
import com.kll.carolinehmibiz.model.SystemModel
import com.kll.carolinehmibiz.net.CarolineNetHelper
import com.kll.carolinehmibiz.net.bean.*
import com.kll.carolinehmibiz.net.listener.DownloadListener
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import okhttp3.ResponseBody
import java.io.*


/**
 * ====================================================
 * Created by Ziliang Cai on 2021/12/12 19:56
 * <a href="mailto:752777456@qq.com">Contact me</a>
 * ====================================================
 */
class SystemPresenter: BasePresenter {



    private constructor(context: Context): super(context){

    }

    companion object {

        private var mInstance: SystemPresenter? = null
        private val WHAT_DOWNLOAD_UPDATE = 1
        private val WHAT_DOWNLOAD_FAILED = 2

        fun getInstance(context: Context): SystemPresenter {
            if(mInstance == null)
                mInstance = SystemPresenter(context)
            return mInstance!!
        }
    }

    /**
     * 获取系统菜单
     */
    fun getSystemAllMenus(parentId: Int, listener: OperateListener) {

        if(parentId == 0) { // 一级菜单

            var menus = SystemModel.getInstance(mContext).getMenus(0)
            if(menus.isNotEmpty()) {
                listener.onSuccess(NetCode.NET_CODE_OK, menus)
            }

            CarolineNetHelper.getInstance(mContext).getSystemAllMenus(object: NetObserver<BaseHttpResult<ArrayList<GetSystemMenuResponse>>>(){
                override fun onSuccess(t: BaseHttpResult<ArrayList<GetSystemMenuResponse>>) {

                    if(t.data?.isNotEmpty() == true) {
                        SystemModel.getInstance(mContext).saveMenu(t.data!!)
                    }

                    listener.onSuccess(t.status, SystemModel.getInstance(mContext).getMenus(0))
                }

                override fun onFail(code: Int, message: String) {
                    listener.onFail(code, message)
                }

            })
        } else { // 二级菜单以上
            listener.onSuccess(NetCode.NET_CODE_OK, SystemModel.getInstance(mContext).getMenus(parentId))
        }
    }

    fun getSystemMenuDetail(menuId: Int, listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).getSystemMenuDetail(menuId, object: NetObserver<BaseHttpResult<ArrayList<GetSystemMenuDetailResponse>>>(){
            override fun onSuccess(t: BaseHttpResult<ArrayList<GetSystemMenuDetailResponse>>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 获取设置
     */
    fun getSetting(code: String, listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).getSetting(code, object:
            NetObserver<BaseHttpResult<GetSettingResponse>>() {
            override fun onSuccess(t: BaseHttpResult<GetSettingResponse>) {
                // 回调登录监听
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }
        })
    }

    /**
     * 获取分配客服
     *
     * @param type 客服类型 1：默认客服，2：基因检测，3：全息影像筛查，4：饮食检测，5：失忆预防检测，6：中医检测，7；睡眠呼吸检测，8；中医康复，9；饮食康复，10；运动健康，11；再生医学康复，12；睡眠障碍康复，13；自助问诊
     */
    fun getAssignCustomerService(type: Int, listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).getAssignCustomerService(type, object: NetObserver<BaseHttpResult<GetAssignCustomerServiceResponse?>>() {
            override fun onSuccess(t: BaseHttpResult<GetAssignCustomerServiceResponse?>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 获取广告
     */
    fun getAds(code: String, listener: OperateListener) {

        // 先从缓存中取并返回
        var content = SpUtils.getInstance().getValueByString(mContext, code)
        if(content != null) {
            listener.onSuccess(NetCode.NET_CODE_OK, Gson().fromJson(content, GetAdsResponse::class.java))
        }

        // 再从网络中取并返回
        CarolineNetHelper.getInstance(mContext).getAds(code, object: NetObserver<BaseHttpResult<GetAdsResponse?>>(){
            override fun onSuccess(t: BaseHttpResult<GetAdsResponse?>) {
                // 读取到时缓存起来
                if(t.data != null) {
                    SpUtils.getInstance().saveValueToSharePerference(mContext, code,  Gson().toJson(t.data))
                }
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }
        })

    }

    /**
     * 上传图片文件
     */
    fun upLoadImageFile(file: File, listener: OperateListener){

        // 获取上传文件需要的token
        CarolineNetHelper.getInstance(mContext).getUploadInfo(object:  NetObserver<BaseHttpResult<GetUploadInfoReponse?>>(){
            override fun onSuccess(t: BaseHttpResult<GetUploadInfoReponse?>) {
                if(t.data != null) {
                    uploadFile(file, t.data!!, listener)
                } else {
                    listener.onFail(NetCode.NET_CODE_ERROR, t.message)
                }
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 上传文件
     */
    private fun uploadFile(file: File, uploadInfo: GetUploadInfoReponse, listener: OperateListener) {

        var url = uploadInfo.token!!.upload_url!!.upload_url
        var key = "${uploadInfo.token!!.dir}${System.currentTimeMillis()}${file.name.substring(file.name.lastIndexOf("."))}"
        var token = uploadInfo.token!!.token

        CarolineNetHelper.getInstance(mContext).uploadImage(url, key, token, file, object: NetObserver<BaseHttpResult<ArrayList<UploadFileResponse>?>>(){
            override fun onSuccess(t: BaseHttpResult<ArrayList<UploadFileResponse>?>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }
        })
    }

    fun downloadFile(url: String, savePath: String, listener: OperateListener) {


        L.e(">>>>>>", "SystemPrenseter>>downloadFile:: url = ${url}, path = ${savePath}")


        var downloadListener = object: DownloadListener {
            override fun onStart(responseBody: ResponseBody) {


                L.e(">>>>>>", "SystemPrenseter>>downloadFile:: onStart")


//                var downloadThread = Thread(DownloadRunable(mContext, savePath, listener, responseBody))
//                downloadThread.start()
                var downloadRun = DownloadRunable(mContext, savePath, listener, responseBody)
                downloadRun.run()
            }

        }

        CarolineNetHelper.getInstance(mContext).downloadFile(url, downloadListener, object: Observer<ResponseBody> {

            override fun onSubscribe(d: Disposable) {
                L.e("======1", "======")
//                downloadListener.onStart(d)
            }

            override fun onNext(response: ResponseBody) {

            }

            override fun onError(e: Throwable) {
                listener.onFail(NetCode.NET_CODE_ERROR, "下载失败")
            }

            override fun onComplete() {
                L.e("======2", "======")
            }

        })
    }

    private class DownloadRunable(context: Context, savePath: String, listener: OperateListener, responseBody: ResponseBody) {

        private var mListener = listener
        private var mResponseBody = responseBody
        private var mContext = context
        private var mSavePath = savePath
        private var downloadFileProcess: DownloadFileProgress? = null
        private var isFinished = false

        private var mHandler = object: Handler(mContext.mainLooper) {
            override fun handleMessage(msg: Message) {
                super.handleMessage(msg)

                when (msg.what) {
                    WHAT_DOWNLOAD_UPDATE -> {
                        if(!isFinished) {
                            isFinished = downloadFileProcess!!.isFinshed
                            mListener.onSuccess(NetCode.NET_CODE_OK, downloadFileProcess)
                        }
                    }
                    WHAT_DOWNLOAD_FAILED -> {
                        mListener.onFail(NetCode.NET_CODE_ERROR, "下载失败")
                    }
                }
            }
        }

        fun run() {
            try {

                L.e(">>>>>>", "SystemPrenseter>>downloadFile>>onResponse:: run")

                // 改成自己需要的存储位置
                val file = File(mSavePath)
                // L.e("------", "SystemPresenter>>downloadFile:: writeResponseBodyToDisk() file=" + file.path)
                if (file.exists()) {
                    file.delete()
                }
//                var inputStream: InputStream? = null
//                var outputStream: OutputStream? = null
                try {
                    val fileReader = ByteArray(4096)
                    val fileSize: Long = mResponseBody!!.contentLength()
                    var fileSizeDownloaded: Long = 0
//                    inputStream = mResponseBody!!.byteStream()
//                    outputStream = FileOutputStream(file)

                    downloadFileProcess = DownloadFileProgress(fileSize)


                    val randomAccessFile = RandomAccessFile(file, "rwd")
                    val tempFileLen = file.length()
                    randomAccessFile.seek(tempFileLen)
                    while (true) {

//                        L.e(">>>>>>", "SystemPrenseter>>downloadFile>>onResponse:: downloading...")
                        val len: Int = mResponseBody.byteStream().read(fileReader)
                        if (len == -1) {
                            break
                        }
                        randomAccessFile.write(fileReader, 0, len)

                        //计算当前下载百分比，并经由回调传出
                        downloadFileProcess!!.progress += len
                        downloadFileProcess!!.percentage = (100 * fileSizeDownloaded / fileSize).toInt()

                        if(!mHandler.hasMessages(WHAT_DOWNLOAD_UPDATE)) {
                            mHandler.sendEmptyMessageDelayed(WHAT_DOWNLOAD_UPDATE, 500)
                        }
//                        downloadByte += len
//                        callbackProgress(
//                            tempFileLen + totalByte,
//                            tempFileLen + downloadByte,
//                            callback
//                        )
                    }
                    randomAccessFile.close();

//                    while (true) {
//                        val read: Int = inputStream.read(fileReader)
//                        if (read == -1) {
//                            break
//                        }
//                        outputStream.write(fileReader, 0, read)
//                        fileSizeDownloaded += read.toLong()
//
//                        //计算当前下载百分比，并经由回调传出
//                        downloadFileProcess!!.progress = fileSizeDownloaded
//                        downloadFileProcess!!.percentage = (100 * fileSizeDownloaded / fileSize).toInt()
//
//                        L.e(">>>>>>", "SystemPrenseter>>downloadFile>>onResponse:: downloading...")
//                        mHandler.sendEmptyMessage(WHAT_DOWNLOAD_UPDATE)
//                    }
//                    outputStream.flush()

                    //
                    downloadFileProcess!!.isFinshed = true
                    mHandler.sendEmptyMessage(WHAT_DOWNLOAD_UPDATE)

                    return
                } catch (ioe: IOException) {
                    ioe.printStackTrace()
                } catch (e: Exception){
                    e.printStackTrace()
                } finally {
//                    inputStream?.close()
//                    outputStream?.close()
                }
            } catch (e: IOException) {
            }

            mHandler.sendEmptyMessage(WHAT_DOWNLOAD_FAILED)
        }

    }

//    class DownloadFileTask(response:ResponseBody): AsyncTask<OperateListener, DownloadFileProgress, DownloadFileProgress>() {
//        var mListener: OperateListener? = null
//        var responseBody = response
//
//        @SuppressLint("WrongThread")
//        override fun doInBackground(vararg listener: OperateListener?): DownloadFileProgress? {
//
//            mListener = listener[0]
//
//            try {
//                // 改成自己需要的存储位置
//                val file = File("保存路径")
//                L.e("------", "SystemPresenter>>downloadFile:: writeResponseBodyToDisk() file=" + file.path)
//                if (file.exists()) {
//                    file.delete()
//                }
//                var inputStream: InputStream? = null
//                var outputStream: OutputStream? = null
//                try {
//                    val fileReader = ByteArray(4096)
//                    val fileSize: Long = responseBody!!.contentLength()
//                    var fileSizeDownloaded: Long = 0
//                    inputStream = responseBody!!.byteStream()
//                    outputStream = FileOutputStream(file)
//
//                    var downloadFileProcess = DownloadFileProgress(fileSize)
//
//                    while (true) {
//                        val read: Int = inputStream.read(fileReader)
//                        if (read == -1) {
//                            break
//                        }
//                        outputStream.write(fileReader, 0, read)
//                        fileSizeDownloaded += read.toLong()
//
//                        //计算当前下载百分比，并经由回调传出
//                        downloadFileProcess.progress = fileSizeDownloaded
//                        downloadFileProcess.percentage = (100 * fileSizeDownloaded / fileSize).toInt()
////                                        onProgressUpdate(downloadFileProcess)
//                        onProgressUpdate(downloadFileProcess)
//                    }
//
////                            if (downloadListener != null) downloadListener.onFinish(file.path)
//                    outputStream.flush()
//                    true
//                    return downloadFileProcess
//                } catch (e: IOException) {
////                            if (downloadListener != null) downloadListener.onError("" + e.getMessage())
//                    false
//                } finally {
//                    inputStream?.close()
//                    outputStream?.close()
//                }
//            } catch (e: IOException) {
//                false
//            }
//
//            return null
//        }
//
//        override fun onProgressUpdate(vararg downloadFileProcess: DownloadFileProgress) {
//            super.onProgressUpdate(*downloadFileProcess)
//            mListener?.onSuccess(NetCode.NET_CODE_OK, downloadFileProcess)
//        }
//
//        override fun onPostExecute(downloadFileProcess: DownloadFileProgress) {
//            super.onPostExecute(downloadFileProcess)
//            if(downloadFileProcess != null) {
//                downloadFileProcess.isFinshed = true
//                mListener?.onSuccess(NetCode.NET_CODE_OK, downloadFileProcess)
//            } else {
//                mListener?.onFail(NetCode.NET_CODE_ERROR)
//            }
//        }
//    }

    /**
     * 获取疾病列表
     */
    fun getDiseases(isFristPage: Boolean, listener: OperateListener) {

        var maxId: Int? = null
        // 获取缓存中的maxId
        var cacheMaxId = SpUtils.getInstance().getValueByInt(mContext,  "DISEASE_MAX_ID")
        if(cacheMaxId > 0) {
            maxId = cacheMaxId
        }

        // 再从网络中获取
        CarolineNetHelper.getInstance(mContext).getDiseases(if(isFristPage) 0 else maxId, object: NetObserver<BaseHttpResult<GetDiseaseResponse?>>() {

            override fun onSuccess(t: BaseHttpResult<GetDiseaseResponse?>) {
                if(t.data != null) {
                    SpUtils.getInstance().saveValueToSharePerference(mContext, "DISEASE_MAX_ID", t.data!!.max_id)
                }
                listener.onSuccess(t.status,  t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })

    }

    /**
     * 获取我的预约
     */
    fun getCalllog(isFristPage: Boolean, listener: OperateListener) {
        var maxId: Int? = null
        // 获取缓存中的maxId
        var cacheMaxId = SpUtils.getInstance().getValueByInt(mContext,  "CALLLOG_MAX_ID")
        if(cacheMaxId > 0) {
            maxId = cacheMaxId
        }

        // 再从网络中获取
        CarolineNetHelper.getInstance(mContext).getCalllog(if(isFristPage) 0 else maxId, object: NetObserver<BaseHttpResult<GetCalllogResponse>>() {

            override fun onSuccess(t: BaseHttpResult<GetCalllogResponse>) {
                if(t.data != null) {
                    SpUtils.getInstance().saveValueToSharePerference(mContext, "CALLLOG_MAX_ID", t.data!!.max_id)
                }
                listener.onSuccess(t.status,  t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    fun getRegion(regionId: Int, listener: OperateListener) {
        // 获取地区
        CarolineNetHelper.getInstance(mContext).getRegion(regionId, object: NetObserver<BaseHttpResult<ArrayList<GetRegionResponse>>>() {
            override fun onSuccess(t: BaseHttpResult<ArrayList<GetRegionResponse>>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 获取收货地址
     */
    fun getAddress(listener: OperateListener) {
        // 获取收货地址
        CarolineNetHelper.getInstance(mContext).getAddress(object : NetObserver<BaseHttpResult<List<GetAddressResponse?>>>(){
            override fun onSuccess(t: BaseHttpResult<List<GetAddressResponse?>>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 添加地址
     */
    fun addAddress(consignee: String, regionList: ArrayList<Int>, address: String, mobile: String, isDefault: Int, listener: OperateListener) {
        // 添加地址
        CarolineNetHelper.getInstance(mContext).addAddress(consignee, regionList, address, mobile, isDefault, object: NetObserver<BaseHttpResult<GetAddressResponse>>(){
            override fun onSuccess(t: BaseHttpResult<GetAddressResponse>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 编辑地址
     */
    fun editAddress(userAddressId: Int, consignee: String, regionList: ArrayList<Int>, region: String, address: String, mobile: String, isDefault: Int, listener: OperateListener) {
        // 添加地址
        CarolineNetHelper.getInstance(mContext).editAddress(userAddressId, consignee, regionList, region, address, mobile, isDefault,
            object: NetObserver<BaseHttpResult<GetAddressResponse>>(){
            override fun onSuccess(t: BaseHttpResult<GetAddressResponse>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 删除地址
     * @param userAddressId 地址: IntArray
     */
    fun delAddress(userAddressId: IntArray, listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).delAddress(userAddressId, object: NetObserver<BaseHttpResult<EmptyResponse>>(){
            override fun onSuccess(t: BaseHttpResult<EmptyResponse>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    fun getAppNewlyVersion(listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).getAppNewlyVersion(object : NetObserver<BaseHttpResult<GetAppNewlyVersionResponse?>>(){
            override fun onSuccess(t: BaseHttpResult<GetAppNewlyVersionResponse?>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 获取每日健康指数
     */
    fun getDaily(sday: String, listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).getDaily(sday, object : NetObserver<BaseHttpResult<ArrayList<DailyResponse>>>(){
            override fun onSuccess(t: BaseHttpResult<ArrayList<DailyResponse>>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 图片列表
     */
    fun getAlbum(isFristPage: Boolean, listener: OperateListener) {
        var maxId: Int? = null
        // 获取缓存中的maxId
        var cacheMaxId = SpUtils.getInstance().getValueByInt(mContext,  "GETALBUM_MAX_ID")
        if(cacheMaxId > 0) {
            maxId = cacheMaxId
        }

        // 再从网络中获取
        CarolineNetHelper.getInstance(mContext).getAlbum(if(isFristPage) 0 else maxId, object : NetObserver<BaseHttpResult<GetPhotoAlbumResponse>>() {
            override fun onSuccess(t: BaseHttpResult<GetPhotoAlbumResponse>) {
                if(t.data != null) {
                    SpUtils.getInstance().saveValueToSharePerference(mContext, "GETALBUM_MAX_ID", t.data!!.max_id)
                }
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 添加图片
     */
    fun addPhoto(list: ArrayList<AddPhoto.Photo>, listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).addPhoto(list, object : NetObserver<BaseHttpResult<EmptyResponse>>() {
            override fun onSuccess(t: BaseHttpResult<EmptyResponse>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

    /**
     * 删除图片
     */
    fun delPhoto(list: ArrayList<Int>, listener: OperateListener) {
        CarolineNetHelper.getInstance(mContext).delPhoto(list, object : NetObserver<BaseHttpResult<EmptyResponse>>() {
            override fun onSuccess(t: BaseHttpResult<EmptyResponse>) {
                listener.onSuccess(t.status, t.data)
            }

            override fun onFail(code: Int, message: String) {
                listener.onFail(code, message)
            }

        })
    }

}